package com.chery.media.library.base

import android.content.Context
import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.ViewModelProvider
import com.blankj.utilcode.util.ScreenUtils
import com.chery.media.library.R
import java.lang.reflect.ParameterizedType

abstract class BaseDialogFragment<VM : BaseViewModel, DB : ViewDataBinding> : DialogFragment() {

    protected lateinit var mContext: Context

    lateinit var mViewModel: VM

    lateinit var mBinding: DB

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setStyle(STYLE_NO_TITLE, R.style.centerDialog)
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        mBinding = DataBindingUtil.inflate(inflater, layoutResId, container, false)
        mBinding.lifecycleOwner = this
        return mBinding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        mContext = dialog!!.context
        mViewModel = createViewModel()
        dialog!!.setCancelable(true)
        dialog!!.setCanceledOnTouchOutside(true)
        initWindow()
        initView(view, arguments)
        createObserver()
    }

    open fun createObserver() {

    }

    override fun onAttach(context: Context) {
        super.onAttach(context)
        mContext = context
    }

    private fun createViewModel(): VM {
        val type = javaClass.genericSuperclass
        if (type is ParameterizedType) {
            val cls = type.actualTypeArguments[0] as Class<VM>
            mViewModel = ViewModelProvider(viewModelStore, defaultViewModelProviderFactory)[cls]
        }
        return mViewModel
    }

    protected abstract val layoutResId: Int

    protected abstract fun initView(view: View?, args: Bundle?)

    protected fun setCancelType(cancelable: Boolean = false, canceledOnTouchOutside: Boolean = false) {
        dialog!!.setCancelable(cancelable)
        dialog!!.setCanceledOnTouchOutside(canceledOnTouchOutside)
    }

    @JvmOverloads
    fun showDialog(manager: FragmentManager, args: Bundle? = null, tag: String = "") {
        if (isAdded) {
            return
        }
        this.arguments = args
        show(manager, tag)
    }

    private fun initWindow() {
        //设置窗口属性
        configWindowPercent(Gravity.BOTTOM, 1f, 0f)
    }

    protected fun configWindowFixSize(gravity: Int, width: Int, height: Int) {
        dialog!!.window!!.setGravity(gravity)
        dialog!!.window!!.setLayout(width, height)
    }

    protected fun configWindowPercent(gravity: Int, widthPercent: Float, heightPercent: Float) {
        val window = dialog!!.window
        window!!.setGravity(gravity)
        val width = (ScreenUtils.getScreenWidth() * widthPercent).toInt()
        val height = (ScreenUtils.getScreenHeight() * heightPercent).toInt()
        if (height > 0) window.setLayout(width, height) else {
            val params = window.attributes
            params.width = width
            window.attributes = params
        }
    }

    protected fun setMaskTransparent() {
        val window = dialog!!.window
        val windowParams = window!!.attributes
        windowParams.dimAmount = 0.0f
        windowParams.width = LinearLayout.LayoutParams.MATCH_PARENT
        windowParams.height = LinearLayout.LayoutParams.WRAP_CONTENT
        window.attributes = windowParams
    }
}